﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace DimensionsHelper.Services.DataTable;

/// <summary>
///     样本表使用的样本对象，记录样本ID和重复出现的次数。
/// </summary>
public class Sample
{
    private int _repetitiveCount = 1;
    private readonly SampleDataTable _table;

    /// <summary>
    ///     样本表使用的样本对象，记录样本ID和重复出现的次数。
    /// </summary>
    public Sample(SampleDataTable table, object id)
    {
        _table = table;
        Id = id;
    }

    /// <summary>
    ///     样本的唯一标识符
    /// </summary>
    public object Id { get; }

    /// <summary>
    ///     当前样本的出现次数。
    /// </summary>
    public double Value
    {
        get
        {
            double factor = 1;

            if (_table.TryGetWeightingFactor(Id, out var wtFactor))
            {
                factor = wtFactor;
            }

            if (_table.Reduplicate)
            {
                if (_table.ApplyWeight)
                {
                    return _repetitiveCount * factor;
                }

                return _repetitiveCount;
            }

            if (_table.ApplyWeight)
            {
                return factor;
            }

            return 1;
        }
    }

    /// <summary>
    ///     当前样本出现次数自增1.
    /// </summary>
    public void Increase()
    {
        _repetitiveCount++;
    }

    /// <summary>
    ///     当前样本出现次数自减1.
    /// </summary>
    public void Decrease()
    {
        if (_repetitiveCount > 0)
        {
            _repetitiveCount--;
        }
    }
}

public class SampleDataCell(SampleDataRow row, SampleDataColumn column, SampleDataTable table)
{
    private readonly Dictionary<object, Sample> _samples = new();
    private double _noSampleData;

    /// <summary>
    ///     当前单元格所在行索引
    /// </summary>
    public int Row => row.RowIndex;

    /// <summary>
    ///     当前单元格所在列索引
    /// </summary>
    public int Column => column.ColumnIndex;

    /// <summary>
    ///     当前单元格内的样本数量。
    /// </summary>
    public int SampleCount => _samples.Count;

    /// <summary>
    ///     当前单元格内样本的数量。如果<see cref="SampleDataTable.Reduplicate" />属性为true，
    ///     此值是样本出现次数的总和。
    /// </summary>
    public double Value
    {
        get
        {
            if (row.Kind == DataRowKind.Base)
            {
                return column.BaseValue;
            }

            if (row.NoSample)
            {
                return _noSampleData;
            }

            return _samples.Values.Sum(sample => sample.Value);
        }

        internal set
        {
            Debug.Assert(row.NoSample, "只有当前行不保存样本时，才允许手动设置单元格值。");
            _noSampleData = value;
        }
    }

    /// <summary>
    ///     向当前单元格追加新的样本ID，如果此ID已存在，将自增已有样本。
    /// </summary>
    /// <param name="sampleId">样本ID，可以是字符串或数字</param>
    public void IncreaseSample(object sampleId)
    {
        Debug.Assert(!row.NoSample, "当前样本行不保存样本。");

        if (_samples.TryGetValue(sampleId, out var sample))
        {
            sample.Increase();
        }
        else
        {
            var newSample = new Sample(table, sampleId);
            _samples.Add(sampleId, newSample);
            column.OnSampleChangedInternal(newSample, SampleChangedType.Add);
        }
    }

    /// <summary>
    ///     将指定样本移除出当前单元格，此时，重复值将自减1，样本集合将直接移除该样本。
    ///     如果给定样本ID不在单元格集合中，将不做任何操作。
    /// </summary>
    /// <param name="sampleId">给定样本ID</param>
    public void DecreaseSample(object sampleId)
    {
        Debug.Assert(!row.NoSample, "当前样本行不保存样本。");

        if (!_samples.TryGetValue(sampleId, out var sample))
        {
            return;
        }

        sample.Decrease();

        if (sample.Value != 0)
        {
            return;
        }

        _samples.Remove(sampleId);
        column.OnSampleChangedInternal(sample, SampleChangedType.Remove);
    }

    /// <summary>
    ///     清空单元格数据。
    /// </summary>
    public void Clear()
    {
        _samples.Clear();
    }
}